package com.runa.monitor.platinterface.netservice.equipment;

import com.runa.monitor.comm.dto.*;
import com.runa.monitor.platinterface.backwork.function.TaskFunction;
import com.runa.monitor.platinterface.netservice.connect.commstatus.CommStatus;
import com.runa.rccprotocol.dto.ConcentratorRequestData;
import com.runa.rccprotocol.dto.en.EnMeterRequestData;
import com.runa.rccprotocol.dto.equdata.EquData;
import com.runa.rccprotocol.dto.lichuang.LiChuangEquRequestData;
import com.runa.rccprotocol.dto.param.ExtendParam;
import com.runa.rccprotocol.dto.runa.RunaRCRequestData;
import com.runa.rccprotocol.dto.zhongrun.ZhongRunEquRequestData;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * @author diandian
 * @Date 2022/5/12 20:05
 */
@Slf4j
public class LiChuangDriver extends NetEqu<String> {
    private static final Logger logger = LoggerFactory.getLogger(LiChuangDriver.class);
    //兰吉尔
    private EnMeterRequestData enRequestData;
    //力创
    private LiChuangEquRequestData liChuangRequestData;
    //瑞纳
    private RunaRCRequestData ruiNaRequestData = null;
    //中润
    private ZhongRunEquRequestData zhongRunRequestData = null;

    public LiChuangDriver(String serial, Integer timeout) {
        super(serial, timeout);
        this.enRequestData = new EnMeterRequestData(serial);
        this.liChuangRequestData = new LiChuangEquRequestData(serial);
        this.ruiNaRequestData = new RunaRCRequestData();
        this.zhongRunRequestData = new ZhongRunEquRequestData(serial);
    }

    @Override
    public void readNodeEqu(List<Node> nodeList, TaskFunction function, EquData.EquDataType type) {
        //如果集中器不在线直接触发离线回调
        if (!online()) {
            function.doApply(CommStatus.OffLine, nodeList);
            return;
        }
        switch (type) {
            case METER:
                readHouseMeter(nodeList, function);
                break;
            case VALVE:
                readHouseValve(nodeList, function);
                break;
            default:
        }
    }

    private void readHouseValve(List<Node> hValves, TaskFunction function) {
        for (Node node : hValves) {
            String model = node.getModel();
            String serial = node.getSerial();
            ConcentratorRequestData concentratorRequestData = null;
            concentratorRequestData = liChuangRequestData;
            liChuangRequestData.readHouseValve(serial);
            concentratorRequestData.setHaveResult(true);
            super.sendRequest(concentratorRequestData, function);
        }
    }

    private void readHouseMeter(List<Node> hMeters, TaskFunction function) {
        for (Node node : hMeters) {
            String model = node.getModel();
            String serial = node.getSerial();
            ConcentratorRequestData concentratorRequestData = null;
            if ("兰吉尔LJ户表".equals(model)) {
                readEN_HouseMeter(node, function);
            } else if ("ZRM型".equals(model)) {
                concentratorRequestData = zhongRunRequestData;
                zhongRunRequestData.readHeatMeter(serial);
                readMeter(node, function, concentratorRequestData);
            } else if ("力创LC户表".equals(model)) {
                concentratorRequestData = liChuangRequestData;
                liChuangRequestData.readHeatMeter(serial);
                readMeter(node, function, concentratorRequestData);
            } else if ("RC型".equals(model)) {
                concentratorRequestData = ruiNaRequestData;
                ruiNaRequestData.readHeatMeter(serial);
                readMeter(node, function, concentratorRequestData);
            }
        }
    }

    private void readMeter(Node node, TaskFunction function, ConcentratorRequestData concentratorRequestData) {
        concentratorRequestData.setHaveResult(true);
        concentratorRequestData.setRemain(Collections.singletonList(node));
        super.sendRequest(concentratorRequestData, function);
    }

    private void readEN_HouseMeter(Node node, TaskFunction function) {
        Boolean initRes = initAndChoose(node.getSerial(), function);
        if (initRes) {
            enRequestData.readHouseMeter();
            super.sendRequest(enRequestData, function);
            destroy();
        }
    }

    private Boolean initAndChoose(String serial, TaskFunction function) {
        LanJiErDriver.EnFunction chooseFunc = new LanJiErDriver.EnFunction(function);
        enRequestData.choseHouseMeter(serial);
        super.sendRequest(enRequestData, chooseFunc);
        Boolean chooseRes = chooseFunc.waitResult();
        return chooseRes;
    }

    private boolean destroy() {
        LanJiErDriver.EnFunction closeFunc = new LanJiErDriver.EnFunction();
        enRequestData.destroy();
        super.sendRequest(enRequestData, closeFunc);
        Boolean closeRes = closeFunc.waitResult();
        return closeRes;
    }

    @Override
    public void setNodeEquArchive(List<Archive> archives, TaskFunction function) {

    }

    @Override
    public void clearNodeEquArchive(TaskFunction function) {

    }

    @Override
    public void valveOnOffControl(List<Node> valveSerial, boolean ifLock, Integer opening, TaskFunction function) {

    }

//    @Override
//    public void valveTemperatureLock(List<String> valveSerial, boolean ifLock, float temperature, TaskFunction function) {
//
//    }
//
//    @Override
//    public void valveTemperatureLimit(List<String> valveSerial, float up, float down, TaskFunction function) {
//
//    }

    @Override
    public void readNodeRecord(List<Integer> indexes, TaskFunction function) {

    }

    @Override
    public void sentPublicUnitRecord(List<Node> valveSerial, Integer model, Map param, TaskFunction function) {

    }

    @Override
    public void sentPublicUnitModel(List<Node> valveSerial, boolean model, TaskFunction function) {

    }

    @Override
    public void sentExtendParam(ExtendParam param, TaskFunction function) {

    }

    @Override
    public void readPublicUnitRecord(Node valveSerial, Integer model, TaskFunction function) {

    }

    @Override
    public void readPublicUnitAndMeter(Node valveSerial, Node meterSerial, TaskFunction function) {

    }

    private long heartbeatInterval = 0;

    @Override
    public void heartbeatUpdate() {
        heartbeatTimestamp = System.currentTimeMillis();
        if (heartbeatTimestamp != 0) {
            //利用5次心跳的时间再加上10s的延迟误差来计算心跳间隔
            long diff = System.currentTimeMillis() - heartbeatTimestamp;
            heartbeatInterval = diff < 5 * 60 * 1000 ? 10 * 60 * 1000 : ((diff) * 5);
        }
    }

    @Override
    public boolean heartStop() {
        return heartbeatTimestamp != 0 && heartbeatInterval != 0 && System.currentTimeMillis() - heartbeatTimestamp > heartbeatInterval;
    }

    @Override
    public Node findMeter(String serial, String netId) {
        return null;
    }

    @Override
    public Node findValve(String serial, String netId) {
        return null;
    }

}
